package org.gdstash.ui.table;

import javax.swing.*;
import javax.swing.table.TableRowSorter;
import java.util.Comparator;

public class GDMassImportSorter extends TableRowSorter<GDMassImportTableModel> {
    private static final int SORTORDER_DEFAULT = 0;
    private static final int SORTORDER_BASE = 1;
    private static final int SORTORDER_BASE_REV = 2;
    private static final int SORTORDER_SELECT = 3;
    private static final int SORTORDER_SELECT_REV = 4;
    private static final int SORTORDER_VALID = 5;
    private static final int SORTORDER_VALID_REV = 6;
    private static final int SORTORDER_ITEMNAME = 7;
    private static final int SORTORDER_ITEMNAME_REV = 8;
    private static final int SORTORDER_LEVEL = 9;
    private static final int SORTORDER_LEVEL_REV = 10;
    private static final int SORTORDER_CHARNAME = 11;
    private static final int SORTORDER_CHARNAME_REV = 12;
    private static final int SORTORDER_SC_HC = 13;
    private static final int SORTORDER_SC_HC_REV = 14;
    private static final Comparator<GDMassImportRow> COMP_BASE;
    private static final Comparator<GDMassImportRow> COMP_BASE_REV;
    private static final Comparator<GDMassImportRow> COMP_SELECT;
    private static final Comparator<GDMassImportRow> COMP_SELECT_REV;
    private static final Comparator<GDMassImportRow> COMP_VALID;
    private static final Comparator<GDMassImportRow> COMP_VALID_REV;
    private static final Comparator<GDMassImportRow> COMP_ITEMNAME;
    private static final Comparator<GDMassImportRow> COMP_ITEMNAME_REV;
    private static final Comparator<GDMassImportRow> COMP_LEVEL;
    private static final Comparator<GDMassImportRow> COMP_LEVEL_REV;
    private static final Comparator<GDMassImportRow> COMP_CHARNAME;
    private static final Comparator<GDMassImportRow> COMP_CHARNAME_REV;
    private static final Comparator<GDMassImportRow> COMP_SC_HC;
    private static final Comparator<GDMassImportRow> COMP_SC_HC_REV;
    private int sortOrder;

    public GDMassImportSorter() {
        this(null);
    }

    public GDMassImportSorter(final GDMassImportTableModel model) {
        this.setModel(model);
    }

    @Override
    public void setModel(final GDMassImportTableModel m) {
        super.setModel(m);
        if (m != null) {
            this.setSortable(0, false);
            this.sortOrder = 0;
        }
    }

    @Override
    public void toggleSortOrder(final int column) {
        if (column == 0) {
            if (this.sortOrder == 3) {
                this.sortOrder = 4;
            } else {
                this.sortOrder = 3;
            }
        }
        if (column == 1) {
            if (this.sortOrder == 5) {
                this.sortOrder = 6;
            } else {
                this.sortOrder = 5;
            }
        }
        if (column == 2) {
            if (this.sortOrder == 1) {
                this.sortOrder = 2;
            } else {
                this.sortOrder = 1;
            }
        }
        if (column == 3) {
            if (this.sortOrder == 7) {
                this.sortOrder = 8;
            } else {
                this.sortOrder = 7;
            }
        }
        if (column == 4) {
            if (this.sortOrder == 9) {
                this.sortOrder = 10;
            } else {
                this.sortOrder = 9;
            }
        }
        if (column == 12) {
            if (this.sortOrder == 11) {
                this.sortOrder = 12;
            } else {
                this.sortOrder = 11;
            }
        }
        if (column == 13) {
            if (this.sortOrder == 13) {
                this.sortOrder = 14;
            } else {
                this.sortOrder = 13;
            }
        }
    }

    static {
        COMP_BASE = new BaseComparator();
        COMP_BASE_REV = new BaseReverseComparator();
        COMP_SELECT = new SelectComparator();
        COMP_SELECT_REV = new SelectReverseComparator();
        COMP_VALID = new ValidComparator();
        COMP_VALID_REV = new ValidReverseComparator();
        COMP_ITEMNAME = new ItemNameComparator();
        COMP_ITEMNAME_REV = new ItemNameReverseComparator();
        COMP_LEVEL = new LevelComparator();
        COMP_LEVEL_REV = new LevelReverseComparator();
        COMP_CHARNAME = new CharNameComparator();
        COMP_CHARNAME_REV = new CharNameReverseComparator();
        COMP_SC_HC = new SCHCComparator();
        COMP_SC_HC_REV = new SCHCReverseComparator();
    }

    @Override
    public void sort() {
        final GDMassImportTableModel model = getModel();
        if (this.sortOrder == 1) {
            model.sort(GDMassImportSorter.COMP_BASE);
        }
        if (this.sortOrder == 2) {
            model.sort(GDMassImportSorter.COMP_BASE_REV);
        }
        if (this.sortOrder == 3) {
            model.sort(GDMassImportSorter.COMP_SELECT);
        }
        if (this.sortOrder == 4) {
            model.sort(GDMassImportSorter.COMP_SELECT_REV);
        }
        if (this.sortOrder == 5) {
            model.sort(GDMassImportSorter.COMP_VALID);
        }
        if (this.sortOrder == 6) {
            model.sort(GDMassImportSorter.COMP_VALID_REV);
        }
        if (this.sortOrder == 7) {
            model.sort(GDMassImportSorter.COMP_ITEMNAME);
        }
        if (this.sortOrder == 8) {
            model.sort(GDMassImportSorter.COMP_ITEMNAME_REV);
        }
        if (this.sortOrder == 9) {
            model.sort(GDMassImportSorter.COMP_LEVEL);
        }
        if (this.sortOrder == 10) {
            model.sort(GDMassImportSorter.COMP_LEVEL_REV);
        }
        if (this.sortOrder == 11) {
            model.sort(GDMassImportSorter.COMP_CHARNAME);
        }
        if (this.sortOrder == 12) {
            model.sort(GDMassImportSorter.COMP_CHARNAME_REV);
        }
        if (this.sortOrder == 13) {
            model.sort(GDMassImportSorter.COMP_SC_HC);
        }
        if (this.sortOrder == 14) {
            model.sort(GDMassImportSorter.COMP_SC_HC_REV);
        }
    }

    public static class BaseComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    private static class BaseReverseComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return -iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    public static class SelectComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            int iSelected = 0;
            if (ir1.selected != ir2.selected) {
                if (ir1.selected) {
                    iSelected = -1;
                } else {
                    iSelected = 1;
                }
            }
            if (iSelected != 0) {
                return iSelected;
            }
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    private static class SelectReverseComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            int iSelected = 0;
            if (ir1.selected != ir2.selected) {
                if (ir1.selected) {
                    iSelected = -1;
                } else {
                    iSelected = 1;
                }
            }
            if (iSelected != 0) {
                return -iSelected;
            }
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    public static class ValidComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            int iValid = 0;
            if (ir1.valid != ir2.valid) {
                if (ir1.valid) {
                    iValid = -1;
                } else {
                    iValid = 1;
                }
            }
            if (iValid != 0) {
                return iValid;
            }
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    private static class ValidReverseComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            int iValid = 0;
            if (ir1.valid != ir2.valid) {
                if (ir1.valid) {
                    iValid = -1;
                } else {
                    iValid = 1;
                }
            }
            if (iValid != 0) {
                return -iValid;
            }
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    public static class ItemNameComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    private static class ItemNameReverseComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return -iName;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    private static class LevelComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    private static class LevelReverseComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return -iLevel;
            }
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    public static class CharNameComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    private static class CharNameReverseComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return -iCharName;
            }
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    public static class SCHCComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            int iSCHC = 0;
            if (ir1.hardcore != ir2.hardcore) {
                if (ir1.hardcore) {
                    iSCHC = 1;
                } else {
                    iSCHC = -1;
                }
            }
            if (iSCHC != 0) {
                return iSCHC;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }

    private static class SCHCReverseComparator implements Comparator<GDMassImportRow> {
        @Override
        public int compare(final GDMassImportRow ir1, final GDMassImportRow ir2) {
            int iSCHC = 0;
            if (ir1.hardcore != ir2.hardcore) {
                if (ir1.hardcore) {
                    iSCHC = 1;
                } else {
                    iSCHC = -1;
                }
            }
            if (iSCHC != 0) {
                return -iSCHC;
            }
            final int iCharName = ir1.charName.text.compareTo(ir2.charName.text);
            if (iCharName != 0) {
                return iCharName;
            }
            final int iBase = ir1.baseName.compareTo(ir2.baseName);
            if (iBase != 0) {
                return iBase;
            }
            final int iLvl1 = Integer.parseInt(ir1.level.text);
            final int iLvl2 = Integer.parseInt(ir2.level.text);
            final int iLevel = iLvl1 - iLvl2;
            if (iLevel != 0) {
                return iLevel;
            }
            final int iName = ir1.name.text.compareTo(ir2.name.text);
            if (iName != 0) {
                return iName;
            }
            if (ir1.item.getStashID() < ir2.item.getStashID()) {
                return -1;
            }
            if (ir1.item.getStashID() > ir2.item.getStashID()) {
                return 1;
            }
            return 0;
        }
    }
}
